07 Service

一、初识Service

1、启动Service和停止Service

1
2
startService(new Intent(MainActivity.this, MyService.class)); // 启动服务
stopService(new Intent(MainActivity.this, MyService.class)); // 停止服务

服务在系统中最多只有一个实例,即使上述代码中创建了两个不同的Intent实例,但是启动和停止的服务是同一个。只创建一个Intent实例也是可以的,如下所示:

1
2
3
4
5
6
7
private Intent mIntent;
...
mIntent = new Intent(MainActivity.this, MyService.class);
...
startService(mIntent);
...
stopService(mIntent);

Service代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.xianxiaotao.learnservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service {
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
System.out.println("MyService onBind");
return new Binder();
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("MyService onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("MyService onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("MyService onDestroy");
}
}

2、绑定Service和解除绑定服务

API:

1
2
3
4
5
6
7
8
// 绑定服务的API
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
return mBase.bindService(service, conn, flags);
}
// 解除绑定服务的API
public void unbindService(ServiceConnection conn) {
mBase.unbindService(conn);
}

实现接口ServiceConnection:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MainActivity extends AppCompatActivity implements ServiceConnection {
private Intent mIntent;
...
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("Service Connected"); // 服务被成功绑定之后执行
}
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("Service Disconnected"); // 服务所在的进程崩溃时或者被kill时执行
}
}

绑定Service和解除绑定Service:

1
2
bindService(mIntent, MainActivity.this, Context.BIND_AUTO_CREATE);
unbindService(MainActivity.this);

二、Service生命周期

1、启动服务生命周期

第一次启动服务日志如下:

1
2
I/System.out: MyService onCreate
I/System.out: MyService onStartCommand

第二、三次启动服务日志:

1
2
I/System.out: MyService onStartCommand
I/System.out: MyService onStartCommand

接着停止服务日志:

1
I/System.out: MyService onDestroy

2、启动服务后并退出

启动服务后并退出当前程序的日志:

1
2
I/System.out: MyService onCreate
I/System.out: MyService onStartCommand

重新启动应用并停止服务:

1
I/System.out: MyService onDestroy

3、绑定服务生命周期

第一次绑定服务日志:

1
2
3
I/System.out: MyService onCreate
I/System.out: MyService onBind
I/System.out: Service Connected

第二、三次绑定服务无任何日志输出
解除绑定服务日志:

1
I/System.out: MyService onDestroy

4、绑定服务并退出

成功绑定服务后并退出当前程序的日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
I/System.out: MyService onCreate
I/System.out: MyService onBind
I/System.out: Service Connected
E/ActivityThread: Activity com.xianxiaotao.learnservice.MainActivity has leaked ServiceConnection com.xianxiaotao.learnservice.MainActivity@f45fa7c that was originally bound here
android.app.ServiceConnectionLeaked: Activity com.xianxiaotao.learnservice.MainActivity has leaked ServiceConnection com.xianxiaotao.learnservice.MainActivity@f45fa7c that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1336)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:1231)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1450)
at android.app.ContextImpl.bindService(ContextImpl.java:1422)
at android.content.ContextWrapper.bindService(ContextWrapper.java:636)
at com.xianxiaotao.learnservice.MainActivity$3.onClick(MainActivity.java:39)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6121)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
I/System.out: MyService onDestroy

如果绑定服务后,请确保在异常情况下解除绑定服务。比如在Activity的onDestroy方法中解除绑定服务。

5、启动服务后绑定服务

启动服务:

1
2
I/System.out: MyService onCreate
I/System.out: MyService onStartCommand

绑定服务:

1
2
I/System.out: MyService onBind
I/System.out: Service Connected

解除绑定服务:无日志
停止服务:

1
I/System.out: MyService onDestroy

总结:

  • 启动服务后可以通过调用stopService()方法停止服务(也可以由其他应用程序调用、或者服务自身调用stopSelf()来停止服务)。
  • 只有第一次启动服务时,系统会调用Service的onCreate和onStartCommand方法,其他只会调用onStartCommand方法。
  • 绑定服务时,系统会调用Service的onCreate、onBind方法,以及ServiceConnection实现类的onServiceConnected方法。
  • 如果绑定了服务,请在停止服务前或退出程序前必须解除服务绑定。